package com.itheima.stock.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Strings;
import com.itheima.stock.common.enums.ResponseCode;
import com.itheima.stock.mapper.SysUserMapper;
import com.itheima.stock.pojo.SysRole;
import com.itheima.stock.pojo.SysUser;
import com.itheima.stock.service.UserService;
import com.itheima.stock.utils.IdWorker;
import com.itheima.stock.vo.req.LoginReqVo;
import com.itheima.stock.vo.req.PutUserRole;
import com.itheima.stock.vo.req.TianJiaReq;
import com.itheima.stock.vo.resp.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Service
public class UserServiceImpl implements UserService {

    //密码加密的spring对象
    @Autowired
    private PasswordEncoder passwordEncoder;

    //dao层的SysUserMapper对象
    @Autowired
    private SysUserMapper sysUserMapper;

    //spring中的redis对象
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    //产生随机数对象,用来我们验证码存储redis的key值
    //分布式环境保证生成唯一的id值
    @Autowired
    private IdWorker idWorker;

    /**
     * 登录验证的方法
     * @param vo
     * @return
     */
    @Override
    public R<LoginRespVo> login(LoginReqVo vo) {
        //利用谷歌插件判断对象参数和用户名密码rkey是不是空,是空就报错
        if (vo == null || Strings.isNullOrEmpty(vo.getUsername()) ||
                Strings.isNullOrEmpty(vo.getPassword()) || Strings.isNullOrEmpty(vo.getRkey())) {
            return R.error(ResponseCode.DATA_ERROR.getMessage());
        }

        //获取redis里面的rkey对象应的验证码
        String rCode = redisTemplate.opsForValue().get(vo.getRkey());

        //判断从redis获取出来的rCode是不是空和比较rCode和用户输入的验证码是不是一致的
        if (Strings.isNullOrEmpty(rCode) || !rCode.equals(vo.getCode())) {
            return R.error(ResponseCode.DATA_ERROR.getMessage());
        }

        //清除redis对应的key值
        redisTemplate.delete(vo.getRkey());

        //根据用户名查询用户信息
        SysUser user = sysUserMapper.findByUserName(vo.getUsername());
        //判断用户名是否存在,存在就判断用户名的密码和用户输入的密码是否一致
        if (user == null || !passwordEncoder.matches(vo.getPassword(), user.getPassword())) {
            return R.error(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage());
        }

        //把po对象赋值到vo对象
        LoginRespVo respVo = new LoginRespVo();
        //复制对象,只要属性名一样就可以赋值
        BeanUtils.copyProperties(user,respVo);
        return R.ok(respVo);

    }


    /**
     * 产生验证码的方法
     * @return
     */
    @Override
    public R<RespCode> generateCaptcha() {
        //生成四位数的验证码---RandomStringUtils对象来自org.apache.commons.lang3
        String checkCode = RandomStringUtils.randomNumeric(4);
        //生成唯一的id值
        long rkey = idWorker.nextId();
        //存储到redis中,用户登录的时候进行验证
        redisTemplate.opsForValue().set(String.valueOf(rkey),checkCode,500, TimeUnit.SECONDS);

        //组合数据,返回给前端
//        HashMap<Object, Object> map = new HashMap<>();
//        map.put("rkey", String.valueOf(rkey));
//        map.put("code", checkCode);
//        return R.ok(map);

        //组合数据返回对象给前端
        RespCode respCode = RespCode.builder().rkey(String.valueOf(rkey)).code(checkCode).build();
        return R.ok(respCode);
    }


    /**
     * 加载用户列表
     * @param pagenum
     * @param pagesize
     * @return
     */
    @Override
    public R<PageResult<SysUser>> findAll(Integer pagenum,Integer pagesize) {
        PageHelper.startPage(pagenum, pagesize);
        List<SysUser> all = sysUserMapper.findAll();
        PageInfo<SysUser> sysUserPageInfo = new PageInfo<>(all);
        PageResult<SysUser> pageResultPageResult = new PageResult<>(sysUserPageInfo);
        return R.ok(pageResultPageResult);
    }

    /**
     * 添加用户
     * @return
     */
    @Override
    public R<TianJiaRes> insertUser(TianJiaReq tianJiaReq) {
        long ids = idWorker.nextId();
        tianJiaReq.setId(String.valueOf(ids));
        int i = sysUserMapper.addUser(tianJiaReq);

        //数据组装
        TianJiaRes tianJiaRes = new TianJiaRes();
        tianJiaRes.setCode("1");
        tianJiaRes.setCode(ResponseCode.SUCCESS.getMessage());

        return R.ok(tianJiaRes);

    }

    @Override
    public R<RoleRes> findRole(String id) {
        List<SysRole> roles = sysUserMapper.findRole(id);
        if (CollectionUtils.isEmpty(roles)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        }
        ArrayList<String> idList = new ArrayList<>();
        for (SysRole role : roles) {
            String id1 = role.getId();
            idList.add(id1);
        }

        //响应数据组合
        RoleRes roleRes = new RoleRes();
        roleRes.setOwnRoleIds(idList);
        roleRes.setAllRole(roles);

        return R.ok(roleRes);
    }


    /**
     * 更新用户权限
     * @param putUserRole
     * @return
     */
    @Override
    public R<TianJiaRes> putUserRole(PutUserRole putUserRole) {
        int i = sysUserMapper.upUserRole(putUserRole);
        TianJiaRes tianJiaRes = new TianJiaRes();
        tianJiaRes.setCode("1");
        tianJiaRes.setMsg("操作成功");
        return R.ok(tianJiaRes);
    }


    /**
     * //删除用户
     * @param ids
     * @return
     */
    @Override
    public R<TianJiaRes> deleteUser(List<String> ids) {
        sysUserMapper.deleteUser(ids);
        sysUserMapper.deleteUser2(ids);
        TianJiaRes tianJiaRes = new TianJiaRes();
        tianJiaRes.setCode("1");
        tianJiaRes.setMsg("2");
        return R.ok(tianJiaRes);
    }


    /**
     * 更改用户信息
     * @param findUser
     * @return
     */
    @Override
    public R<TianJiaRes> updateUser(FindUser findUser) {
        sysUserMapper.updateUser(findUser);
        TianJiaRes tianJiaRes = new TianJiaRes();
        tianJiaRes.setCode("1");
        tianJiaRes.setMsg("操作成功");
        return R.ok(tianJiaRes);
    }
}
